package com.github.shiqiyue.app.common.filter;

import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/***
 * 可配置忽略路径的filter
 * @author wenyao.wu
 * @since 2020年4月29日
 */
public abstract class PathConfigurableFilter extends OncePerRequestFilter {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();


    /***
     * 不校验的链接地址
     */
    private List<String> ignorePathList = new ArrayList<>();
    /***
     * 校验的链接地址
     */
    private List<String> securePathList = new ArrayList<>();

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String servletPath = httpServletRequest.getServletPath();
        for (String ignorePath : ignorePathList) {
            if (antPathMatcher.match(ignorePath, servletPath)) {
                filterChain.doFilter(httpServletRequest, httpServletResponse);
                return;
            }
        }
        boolean isSecure = false;
        for (String securePath : securePathList) {
            if (antPathMatcher.match(securePath, servletPath)) {
                isSecure = true;

            }
        }
        if (!isSecure) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
            return;
        }
        doFiltering(httpServletRequest, httpServletResponse, filterChain);
    }

    /***
     * 添加不校验的链接地址
     * @param ignorePath
     */
    public PathConfigurableFilter addIgnorePath(String ignorePath) {
        ignorePathList.add(ignorePath);
        return this;
    }

    /***
     * 添加校验的链接地址
     * @param securePath
     * @return
     */
    public PathConfigurableFilter addSecurePath(String securePath) {
        securePathList.add(securePath);
        return this;
    }

    public void setIgnorePathList(List<String> ignorePathList) {
        this.ignorePathList = ignorePathList;
    }

    public void setSecurePathList(List<String> securePathList) {
        this.securePathList = securePathList;
    }

    protected abstract void doFiltering(
            HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException;

}
